// // Copyright (c) 2009 All Right Reserved // // Stephen Toub // stoub@microsoft.com // 2009-01-01 // Contains ... namespace LargoCommon.Midi { using Abstract; using JetBrains.Annotations; using Music; using System; using System.Globalization; using System.IO; using System.Text; /// MIDI event to modify the pitch of all notes played on the channel. [Serializable] public sealed class VoicePitchWheel : VoiceEvent { #region Fields /// The category status byte for PitchWheel messages. private const byte CategoryStatusByte = 0xE; /// The upper 7-bits of the wheel position.. private byte upperBits; /// The lower 7-bits of the wheel position.. private byte lowerBits; #endregion #region Constructors /// Initializes a new instance of the VoicePitchWheel class. /// The delta-time since the previous message. /// The channel to which to write the message (0 through 15). /// The upper 7 bits of the position. /// The lower 7 bits of the position. public VoicePitchWheel(long deltaTime, MidiChannel channel, byte upperBits, byte lowerBits) : base(deltaTime, CategoryStatusByte, channel) { this.UpperBits = upperBits; this.LowerBits = lowerBits; } /// Initializes a new instance of the VoicePitchWheel class. /// The amount of time before this event. /// The category identifier (0x0 through 0xF) for this voice event. /// The channel (0x0 through 0xF) for this voice event. public VoicePitchWheel(long deltaTime, byte givenCategory, MidiChannel channel) : base(deltaTime, givenCategory, channel) { } #endregion #region Properties /// Gets The first parameter as sent in the MIDI message. /// General musical property. public override byte Parameter1 => (byte)((this.Position & DefaultValue.MaskFirstByte) >> 8); /// Gets The second parameter as sent in the MIDI message. /// General musical property. public override byte Parameter2 => (byte)(this.Position & 0xFF); /// Gets or sets the upper 7 bits of the position. /// General musical property. private byte UpperBits { get => this.upperBits; set { if (this.upperBits > 0x7F) { throw new ArgumentOutOfRangeException(nameof(value), value, "Value must be in the range from 0x0 to 0x7F."); } this.upperBits = value; } } /// Gets or sets the lower 7 bits of the position. /// General musical property. private byte LowerBits { get => this.lowerBits; set { if (this.lowerBits > 0x7F) { throw new ArgumentOutOfRangeException(nameof(value), value, "Value must be in the range from 0x0 to 0x7F."); } this.lowerBits = value; } } /// Gets or sets the wheel position. /// General musical property. private int Position { get => MidiEvent.CombineBytesTo14Bits(this.upperBits, this.lowerBits); [UsedImplicitly] set { if (value < 0 || value > 0x3FFF) { throw new ArgumentOutOfRangeException(nameof(value), value, "Pitch wheel position must be in the range from 0x0 to 0x3FFF."); } MidiEvent.Split14BitsToBytes(value, out this.upperBits, out this.lowerBits); } } #endregion #region To String /// Generate a string representation of the event. /// A string representation of the event. public override string ToString() { var sb = new StringBuilder(); sb.Append(base.ToString()); sb.Append("\t"); sb.Append(this.Position.ToString(CultureInfo.CurrentCulture.NumberFormat)); sb.Append(" ("); sb.Append(this.LowerBits.ToString(CultureInfo.CurrentCulture.NumberFormat)); sb.Append(","); sb.Append(this.UpperBits.ToString(CultureInfo.CurrentCulture.NumberFormat)); sb.Append(")"); return sb.ToString(); } #endregion #region Methods /// Write the event to the output stream. /// The stream to which the event should be written. public override void Write(Stream outputStream) { if (outputStream == null) { return; } //// Write out the base event information base.Write(outputStream); // Write out the data //// int position = this.Position; outputStream.WriteByte(this.Parameter1); outputStream.WriteByte(this.Parameter2); } #endregion } }